﻿using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Xource.Helper
{
    public static partial class XourceHandler
    {
        /// <summary>
        /// Runtime method: Initializes resources from local excel file Xource\Content.xlsx
        /// </summary>
        public static void Initialize(LocalizationMode mode = LocalizationMode.Default, bool enableMonitor = false)
        {
            Initialize(GetLocalFile(), mode, enableMonitor);
        }

        /// <summary>
        /// Runtime method. Initializes resources from excel file
        /// </summary>
        public static void Initialize(string filepath, LocalizationMode mode = LocalizationMode.Default, bool enableMonitor = false)
        {
            if (File.Exists(filepath))
            {
                Stream stream = GetStreamFromFile(filepath);
                Initialize(stream, mode, enableMonitor);
            }
            else
            {
                throw new XourceException(string.Format("File {0} not found", filepath));
            }
        }

        /// <summary>
        /// Runtime method. Initializes resources from stream
        /// </summary>
        public static void Initialize(Stream input, LocalizationMode mode = LocalizationMode.Default, bool enableMonitor = false)
        {
            try
            {
                localizationMode = mode;
                enableMonitorFlag = enableMonitor;
                textCollection = new Dictionary<string, Dictionary<LanguageInfo, string>>();
                // Open and read the XlSX file.
                using (var package = new ExcelPackage(input))
                {
                    // Get the work book in the file
                    ExcelWorkbook workBook = package.Workbook;
                    if (workBook != null)
                    {
                        var worksheet = workBook.Worksheets.Where(q => q.Name.Equals(_WorksheetName)).FirstOrDefault();
                        if (worksheet != null)
                        {
                            // 1. Load content keys
                            var contentKeys = LoadContentKeys(worksheet);
                            // 2. Load available languages
                            LoadLanguages(worksheet);
                            foreach (var contentKey in contentKeys)
                            {
                                textCollection.Add(contentKey.ToString()
                                    , new Dictionary<LanguageInfo, string>());
                                foreach (var language in languages)
                                {
                                    string text = string.Empty;
                                    if (worksheet.Cells[contentKey.Row, language.Column].Value != null
                                        && !string.IsNullOrWhiteSpace(worksheet.Cells[contentKey.Row, language.Column].Value.ToString()))
                                    {
                                        text = worksheet.Cells[contentKey.Row, language.Column].Value.ToString();
                                    }
                                    textCollection[contentKey.ToString()].Add(
                                          language
                                        , text);
                                }
                            }
                        }
                        else
                        {
                            throw new XourceException(string.Format("Worksheet {0} not found", _WorksheetName));
                        }
                    }
                }
                if (enableMonitorFlag)
                {
                    XourceMonitor.Initialize();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        internal static void ReInitialize()
        {
            textCollection.Clear();
            Initialize(localizationMode, enableMonitorFlag);
        }

        /// <summary>
        /// Runtime method: Retrieves all available languages in the worksheet.
        /// Use case example: populating client drop down with available languages.
        /// </summary>
        public static List<LanguageInfo> GetLanguagesInfo()
        {
            return languages;
        }

        public static string GetContent(string contentKey)
        {
            string result = contentKey;
            LanguageInfo languageInfo = GetLanguage();
            result = textCollection[contentKey][languageInfo];
            // Checking if content available for given language and if language is default
            if (string.IsNullOrWhiteSpace(result) && languageInfo != GetDefaultLanguage())
            {
                // Getting fallback text with default language
                languageInfo = GetDefaultLanguage();
                result = textCollection[contentKey][languageInfo];
                // Checking if content available for default language as well
                if (string.IsNullOrWhiteSpace(result))
                {
                    result = contentKey;
                }
            }
            return result;
        }

        public static Dictionary<string, string> GetAllContent()
        {   
            LanguageInfo languageInfo = GetLanguage();
            Dictionary<string, string> result = new Dictionary<string, string>();
            foreach(var textData in textCollection)
            {
                string text = string.Empty;
                try
                {
                    var content = textData.Value.Where(q => q.Key.Equals(languageInfo)).FirstOrDefault();
                    text = content.Value;
                }
                catch { }
                result.Add(textData.Key, text);
            }
            return result;
        }

        public static LanguageInfo GetLanguage()
        {
            LanguageInfo languageInfo = GetDefaultLanguage();
            if(HttpContext.Current.Session != null)
            {
                if (HttpContext.Current.Session[_SessionKey] == null)
                {
                    if (localizationMode == LocalizationMode.Adaptive)
                    {
                        var clientPreference = HttpContext.Current.Request.UserLanguages.FirstOrDefault();
                        if (clientPreference != null)
                        {
                            var tempLanguageInfo = new LanguageInfo(clientPreference, 0);
                            tempLanguageInfo = GetLanguageByLCID(tempLanguageInfo.LCID);
                            if (tempLanguageInfo != null)
                            {
                                languageInfo = tempLanguageInfo;
                            }
                        }
                    }
                    HttpContext.Current.Session[_SessionKey] = languageInfo;
                }
                else
                {
                    languageInfo = HttpContext.Current.Session[_SessionKey] as LanguageInfo;
                }
            }
            return languageInfo;
        }

        public static void SetLanguage(CultureInfo cultureInfo)
        {
            var tempLanguage = GetLanguageByLCID(cultureInfo.LCID);
            if(tempLanguage != null)
            {
                HttpContext.Current.Session[_SessionKey] = tempLanguage;
            }
            else
            {
                throw new XourceException("Unsupported language provided");
            }
        }
    }
}
